package util
{
	import flash.display.Bitmap;
	import flash.display.Loader;
	import flash.events.Event;
	import flash.events.IOErrorEvent;
	import flash.events.SecurityErrorEvent;
	import flash.net.URLRequest;
	import flash.net.URLStream;
	import flash.utils.ByteArray;
	

	public class BitmapLoader extends Bitmap
	{
		private var _imgStream:URLStream = new URLStream();
		private var _imgData:ByteArray   = new ByteArray();
		private var _imgLoader:Loader    = null;	
		private var _url:String;

		public function BitmapLoader()
		{
			super();
					
			_imgStream.addEventListener(Event.COMPLETE, streamCompleteHandler);
			_imgStream.addEventListener(IOErrorEvent.IO_ERROR, streamIOErrorHandler);
			_imgStream.addEventListener(SecurityErrorEvent.SECURITY_ERROR, streamSecErrorHandler);			
		}

		public function load(request:URLRequest):void
		{
			_url = request.url;
									
			_imgLoader = new Loader();		
			_imgStream.load(request);
		}

		private function streamCompleteHandler(e:Event):void
		{
		    _imgStream.readBytes(_imgData);

			if(_imgStream.connected)
				_imgStream.close();

			if(_imgData.length<1)
			{
				streamInvalidDataHandler("length0");
				return;
			}
			
			_imgLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, loadByteCompleteHandler);
			_imgLoader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, ioErrorEventHandler)
			_imgLoader.loadBytes(_imgData);		
		}

		private function streamIOErrorHandler(e:IOErrorEvent):void
		{
			trace("streamIOErrorHandler::"+e.toString());
		}

		private function streamSecErrorHandler(e:SecurityErrorEvent):void
		{
			trace("streamSecErrorHandler::"+e.toString());
		}

		private function streamInvalidDataHandler(msg:String=""):void
		{
			trace("streamInvalidDataHandler::"+msg);
		}		

		public function loadByteCompleteHandler(e:Event):void
		{
			if(_imgLoader && _imgLoader.contentLoaderInfo)
			{
				var newBitmap:Bitmap = _imgLoader.contentLoaderInfo.content as Bitmap;				
				try
				{
					if(newBitmap) this.bitmapData = newBitmap.bitmapData.clone();
					
					disposeLoader();														
				}
				catch (error:Error)
				{
					trace("loaderArgfErrorEventHandler::"+error.toString());
				}
			}
						
			this.dispatchEvent(new Event(Event.COMPLETE));
		}

		private function ioErrorEventHandler(e:IOErrorEvent):void
		{
			trace("loaderIOErrorEventHandler::"+e.toString());
		}

		private function disposeLoader():void
		{
			if(_imgLoader && _imgLoader.content)
			{
				_imgLoader.contentLoaderInfo.removeEventListener(Event.COMPLETE, loadByteCompleteHandler);
				_imgLoader.contentLoaderInfo.removeEventListener(IOErrorEvent.IO_ERROR, ioErrorEventHandler);

				Bitmap(_imgLoader.content).bitmapData.dispose();
				
				_imgLoader.unload();
				_imgLoader = null;	
			}
		}
		
		public function dispose():void
		{
			if(this.bitmapData) this.bitmapData.dispose();
		}
		
		public function get urlStream():URLStream
		{
			return _imgStream;
		}
		public function get loader():Loader
		{
			return _imgLoader;
		}		
	}
}